using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using UnityEngine;


[GeneratedCode("reflection-utils", "1.0.0")]
internal class ReflectionsUtils
{
    public delegate object GetDelegate(object source);

    public delegate void SetDelegate(object source, object value);

    public delegate object ConstructorDelegate(params object[] args);

    public delegate TValue ThreadSafeDictionaryValueFactory<TKey, TValue>(TKey key);

    public sealed class ThreadSafeDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable
    {
        private readonly object _lock = new object();

        private readonly ReflectionsUtils.ThreadSafeDictionaryValueFactory<TKey, TValue> _valueFactory;

        private Dictionary<TKey, TValue> _dictionary;

        public ICollection<TKey> Keys
        {
            get
            {
                return this._dictionary.Keys;
            }
        }

        public ICollection<TValue> Values
        {
            get
            {
                return this._dictionary.Values;
            }
        }

        public TValue this[TKey key]
        {
            get
            {
                return this.Get(key);
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public int Count
        {
            get
            {
                return this._dictionary.Count;
            }
        }

        public bool IsReadOnly
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public ThreadSafeDictionary(ReflectionsUtils.ThreadSafeDictionaryValueFactory<TKey, TValue> valueFactory)
        {
            this._valueFactory = valueFactory;
        }

        private TValue Get(TKey key)
        {
            TValue result;
            TValue tValue;
            if (this._dictionary == null)
            {
                result = this.AddValue(key);
            }
            else if (!this._dictionary.TryGetValue(key, out tValue))
            {
                result = this.AddValue(key);
            }
            else
            {
                result = tValue;
            }
            return result;
        }

        private TValue AddValue(TKey key)
        {
            TValue tValue = this._valueFactory(key);
            object @lock = this._lock;
            TValue result;
            lock (@lock)
            {
                if (this._dictionary == null)
                {
                    this._dictionary = new Dictionary<TKey, TValue>();
                    this._dictionary[key] = tValue;
                }
                else
                {
                    TValue tValue2;
                    if (this._dictionary.TryGetValue(key, out tValue2))
                    {
                        result = tValue2;
                        return result;
                    }
                    Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>(this._dictionary);
                    dictionary[key] = tValue;
                    this._dictionary = dictionary;
                }
            }
            result = tValue;
            return result;
        }

        public void Add(TKey key, TValue value)
        {
            throw new NotImplementedException();
        }

        public bool ContainsKey(TKey key)
        {
            return this._dictionary.ContainsKey(key);
        }

        public bool Remove(TKey key)
        {
            throw new NotImplementedException();
        }

        public bool TryGetValue(TKey key, out TValue value)
        {
            value = this[key];
            return true;
        }

        public void Add(KeyValuePair<TKey, TValue> item)
        {
            throw new NotImplementedException();
        }

        public void Clear()
        {
            throw new NotImplementedException();
        }

        public bool Contains(KeyValuePair<TKey, TValue> item)
        {
            throw new NotImplementedException();
        }

        public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        public bool Remove(KeyValuePair<TKey, TValue> item)
        {
            throw new NotImplementedException();
        }

        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            return this._dictionary.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this._dictionary.GetEnumerator();
        }
    }

    private static readonly object[] EmptyObjects = new object[0];

    public static Attribute GetAttribute(MemberInfo info, Type type)
    {
        Attribute result;
        if (info == null || type == null || !Attribute.IsDefined(info, type))
        {
            result = null;
        }
        else
        {
            result = Attribute.GetCustomAttribute(info, type);
        }
        return result;
    }

    public static Attribute GetAttribute(Type objectType, Type attributeType)
    {
        Attribute result;
        if (objectType == null || attributeType == null || !Attribute.IsDefined(objectType, attributeType))
        {
            result = null;
        }
        else
        {
            result = Attribute.GetCustomAttribute(objectType, attributeType);
        }
        return result;
    }

    public static Type[] GetGenericTypeArguments(Type type)
    {
        return type.GetGenericArguments();
    }

    public static bool IsTypeGenericeCollectionInterface(Type type)
    {
        bool result;
        if (!type.IsGenericType)
        {
            result = false;
        }
        else
        {
            Type genericTypeDefinition = type.GetGenericTypeDefinition();
            result = (genericTypeDefinition == typeof(IList<>) || genericTypeDefinition == typeof(ICollection<>) || genericTypeDefinition == typeof(IEnumerable<>));
        }
        return result;
    }

    public static bool IsAssignableFrom(Type type1, Type type2)
    {
        return type1.IsAssignableFrom(type2);
    }

    public static bool IsTypeDictionary(Type type)
    {
        bool result;
        if (typeof(IDictionary).IsAssignableFrom(type))
        {
            result = true;
        }
        else if (!type.IsGenericType)
        {
            result = false;
        }
        else
        {
            Type genericTypeDefinition = type.GetGenericTypeDefinition();
            result = (genericTypeDefinition == typeof(IDictionary<,>));
        }
        return result;
    }

    public static bool IsNullableType(Type type)
    {
        return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
    }

    public static object ToNullableType(object obj, Type nullableType)
    {
        return (obj != null) ? Convert.ChangeType(obj, Nullable.GetUnderlyingType(nullableType), CultureInfo.InvariantCulture) : null;
    }

    public static bool IsValueType(Type type)
    {
        return type.IsValueType;
    }

    public static IEnumerable<ConstructorInfo> GetConstructors(Type type)
    {
        return type.GetConstructors();
    }

    public static ConstructorInfo GetConstructorInfo(Type type, params Type[] argsType)
    {
        IEnumerable<ConstructorInfo> constructors = ReflectionsUtils.GetConstructors(type);
        ConstructorInfo result;
        foreach (ConstructorInfo current in constructors)
        {
            ParameterInfo[] parameters = current.GetParameters();
            if (argsType.Length == parameters.Length)
            {
                int num = 0;
                bool flag = true;
                ParameterInfo[] parameters2 = current.GetParameters();
                for (int i = 0; i < parameters2.Length; i++)
                {
                    ParameterInfo parameterInfo = parameters2[i];
                    if (parameterInfo.ParameterType != argsType[num])
                    {
                        flag = false;
                        break;
                    }
                }
                if (flag)
                {
                    result = current;
                    return result;
                }
            }
        }
        result = null;
        return result;
    }

    public static IEnumerable<PropertyInfo> GetProperties(Type type)
    {
        return type.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
    }

    public static IEnumerable<FieldInfo> GetFields(Type type)
    {
        return type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
    }

    public static MethodInfo GetGetterMethodInfo(PropertyInfo propertyInfo)
    {
        return propertyInfo.GetGetMethod(true);
    }

    public static MethodInfo GetSetterMethodInfo(PropertyInfo propertyInfo)
    {
        return propertyInfo.GetSetMethod(true);
    }

    public static ReflectionsUtils.ConstructorDelegate GetContructor(ConstructorInfo constructorInfo)
    {
        return ReflectionsUtils.GetConstructorByReflection(constructorInfo);
    }

    public static ReflectionsUtils.ConstructorDelegate GetContructor(Type type, params Type[] argsType)
    {
        return ReflectionsUtils.GetConstructorByReflection(type, argsType);
    }

    public static ReflectionsUtils.ConstructorDelegate GetConstructorByReflection(ConstructorInfo constructorInfo)
    {
        return (object[] args) => constructorInfo.Invoke(args);
    }

    public static ReflectionsUtils.ConstructorDelegate GetConstructorByReflection(Type type, params Type[] argsType)
    {
        ConstructorInfo constructorInfo = ReflectionsUtils.GetConstructorInfo(type, argsType);
        return (constructorInfo != null) ? ReflectionsUtils.GetConstructorByReflection(constructorInfo) : null;
    }

    public static ReflectionsUtils.GetDelegate GetGetMethod(PropertyInfo propertyInfo)
    {
        return ReflectionsUtils.GetGetMethodByReflection(propertyInfo);
    }

    public static ReflectionsUtils.GetDelegate GetGetMethod(FieldInfo fieldInfo)
    {
        return ReflectionsUtils.GetGetMethodByReflection(fieldInfo);
    }

    public static ReflectionsUtils.GetDelegate GetGetMethodByReflection(PropertyInfo propertyInfo)
    {
        MethodInfo methodInfo = ReflectionsUtils.GetGetterMethodInfo(propertyInfo);
        //Debug.Log("propertyInfo :" + propertyInfo.Name);
        //Debug.Log("methodInfo :"+ methodInfo.Name);
        return (object source) => methodInfo.Invoke(source, ReflectionsUtils.EmptyObjects);
    }

    public static ReflectionsUtils.GetDelegate GetGetMethodByReflection(FieldInfo fieldInfo)
    {
        return (object source) => fieldInfo.GetValue(source);
    }

    public static ReflectionsUtils.SetDelegate GetSetMethod(PropertyInfo propertyInfo)
    {
        return ReflectionsUtils.GetSetMethodByReflection(propertyInfo);
    }

    public static ReflectionsUtils.SetDelegate GetSetMethod(FieldInfo fieldInfo)
    {
        return ReflectionsUtils.GetSetMethodByReflection(fieldInfo);
    }

    public static ReflectionsUtils.SetDelegate GetSetMethodByReflection(PropertyInfo propertyInfo)
    {
        MethodInfo methodInfo = ReflectionsUtils.GetSetterMethodInfo(propertyInfo);
        return delegate (object source, object value)
        {
            methodInfo.Invoke(source, new object[]
            {
                    value
            });
        };
    }

    public static ReflectionsUtils.SetDelegate GetSetMethodByReflection(FieldInfo fieldInfo)
    {
        return delegate (object source, object value)
        {
            fieldInfo.SetValue(source, value);
        };
    }
}
